
//	------------------------------------------------------------------------------
//                                       _                          
//              _ __ ___   ___ _ __ ___ | |__  _ __ __ _ _ __   ___ 
//             | '_ ` _ \ / _ \ '_ ` _ \| '_ \| '__/ _` | '_ \ / _ \
//             | | | | | |  __/ | | | | | |_) | | | (_| | | | |  __/
//             |_| |_| |_|\___|_| |_| |_|_.__/|_|  \__,_|_| |_|\___|
//                                                     
//	------------------------------------------------------------------------------

#region - License -
//
//	------------------------------------------------------------------------------                                                   
//	         Copyright (c) 2010 Peter Vyvey (peter.vyvey@chiliware.be)
//	------------------------------------------------------------------------------
//
//
//	This file is part of CHILIWARE MEMBRANE.
//
//	CHILIWARE MEMBRANE is free software: you can redistribute it and/or modify
//	it under the terms of the GNU Lesser General Public License as published by
//	the Free Software Foundation, either version 3 of the License, or
//	(at your option) any later version.
//
//	CHILIWARE MEMBRANE is distributed in the hope that it will be useful,
//	but WITHOUT ANY WARRANTY; without even the implied warranty of
//	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//	GNU Lesser General Public License for more details.
//
//	You should have received a copy of the GNU Lesser General Public License
//	along with CHILIWARE MEMBRANE.  If not, see <http://www.gnu.org/licenses/>.
//
//
#endregion

#region - Changes -
//
//	peter.vyvey@chiliware.be		2010-08-10		Created
//
#endregion

#region - Using -

using System;
using System.Reflection;
using System.IO;
using Chiliware.Membrane.Extension;

#endregion

namespace Chiliware.Membrane.Runtime.Reflection
{
	#region - CommonFactory -

	/// <summary>
	/// Factory class to create instances of object via type information.
	/// </summary>
	public static class CommonFactory
	{
		#region - Public static methods -

		/// <summary>
		/// Parses the given string for type information.
		/// </summary>
		/// <param name="typeInformation">The string value to parse.</param>
		/// <returns>An instance of <see cref="TypeInformation"/>.</returns>
		public static TypeInformation GetTypeInformation(string typeInformation)
		{
			string[] typeInformationSplit = typeInformation.Split(Convert.ToChar(","));

			return new TypeInformation(typeInformationSplit[0].Trim(), typeInformationSplit[1].Trim());
		}

		/// <summary>
		/// Gets the runtime type for the given type information.
		/// </summary>
		/// <param name="typeInformation">The <see cref="TypeInformation"/>.</param>
		/// <returns>The runtime type.</returns>
		public static Type GetType(TypeInformation typeInformation)
		{
			return CommonFactory.GetType(typeInformation.TypeName, typeInformation.AssemblyName);
		}

		/// <summary>
		/// Gets the runtime type for the given type information.
		/// </summary>
		/// <param name="typeName">The type name.</param>
		/// <param name="assemblyName">The assembly name.</param>
		/// <returns>The runtime type.</returns>
		public static Type GetType(string typeName, string assemblyName)
		{

			String assemblyFileName = Assembly.GetExecutingAssembly().EscapedCodeBase;
			Uri ur = new Uri(assemblyFileName);
			assemblyFileName = ur.LocalPath;

			string fileName = string.Format("{0}{1}{2}.dll", Path.GetDirectoryName(assemblyFileName), Path.DirectorySeparatorChar, assemblyName);
			Type type = Assembly.LoadFrom(fileName).GetType(typeName);

			return type;
		}

		/// <summary>
		/// Creates an instance of a type.
		/// </summary>
		/// <typeparam name="T">The type to create.</typeparam>
		/// <param name="typeInformation">The string value containing the type information.</param>
		/// <returns>An instance of the type in the type information casted to T.</returns>
		public static T CreateInstance<T>(string typeInformation)
		{
			TypeInformation info = GetTypeInformation(typeInformation);
			return CommonFactory.CreateInstance<T>(info);
		}

		/// <summary>
		/// Creates an instance of a type.
		/// </summary>
		/// <typeparam name="T">The type to create.</typeparam>
		/// <param name="typeInformation">The <see cref="TypeInformation"/>.</param>
		/// <returns>An instance of the type in the type information casted to T.</returns>
		public static T CreateInstance<T>(TypeInformation typeInformation)
		{
			Type type = CommonFactory.GetType(typeInformation);
			T instance = Activator.CreateInstance(type).CastTo<T>();

			return instance;
		}

		#endregion
	}

	#endregion
}
